home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 2
/
AACD 2.iso
/
AACD
/
Magazine
/
GraphicsCards
/
StormMesa
/
src
/
asm_mmx.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-02-04
|
5KB
|
190 lines
/* $Id: asm_mmx.c,v 1.1 1998/03/27 04:40:07 brianp Exp $ */
/*
* Mesa 3-D graphics library
* Version: 3.0
* Copyright (C) 1995-1998 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* $Log: asm_mmx.c,v $
* Revision 1.1 1998/03/27 04:40:07 brianp
* Initial revision
*
*/
#ifdef MMX
void gl_mmx_blend_transparency( GLcontext *ctx, GLuint n, const GLubyte mask[],
GLubyte rgba[][4], const GLubyte dest[][4] )
{
long long SUBMASK =0x00ff000000ff0000LL;
long long HIGHMASK =0xFFFFFFFF00000000LL;
long long LOWMASK =0x00000000FFFFFFFFLL;
GLuint i;
ASSERT(ctx->Color.BlendEquation==GL_FUNC_ADD_EXT);
ASSERT(ctx->Color.BlendSrc==GL_SRC_ALPHA);
ASSERT(ctx->Color.BlendDst==GL_ONE_MINUS_SRC_ALPHA);
if(((unsigned long)rgba&4 + (unsigned long)dest&4 ) == 8) {
GLint t = rgba[0][ACOMP]; /* t in [0,255] */
GLint s = 255 - t;
GLint r = (rgba[0][RCOMP] * t + dest[0][RCOMP] * s) >> 8;
GLint g = (rgba[0][GCOMP] * t + dest[0][GCOMP] * s) >> 8;
GLint b = (rgba[0][BCOMP] * t + dest[0][BCOMP] * s) >> 8;
GLint a = (rgba[0][ACOMP] * t + dest[0][ACOMP] * s) >> 8;
rgba[0][RCOMP] = r;
rgba[0][GCOMP] = g;
rgba[0][BCOMP] = b;
rgba[0][ACOMP] = a;
mask++;
rgba++;
dest++;
n--;
/*puts("odd adress!");*/
}
if(n) {
for (i=0;i<n/2;i++) {
if (mask[i*2]) {
__asm__ (
"movq (%0), %%mm4\n\t" /* mm4 = rgba[i] rgba[i+1]*/
"pxor %%mm5,%%mm5\n\t"
"movq %%mm4, %%mm1\n\t"
"movq (%1), %%mm7\n\t" /* mm7 = dest[i] dest[i+1] */
"punpcklbw %%mm5, %%mm1\n\t" /* mm1 = rgba[i] */
"movq %%mm7, %%mm6\n\t"
"movq %%mm1, %%mm0\n\t"
"punpcklbw %%mm5, %%mm6\n\t" /* mm6 = dest[i] */
"movq %%mm1, %%mm2\n\t" /* mm2 = rgba[i] */
"psrlq $48, %%mm0\n\t" /* mm0 = mm0 & 0xFF */
"punpckhbw %%mm5, %%mm4\n\t" /* mm4 = rgba[i+1] */
"packssdw %%mm0, %%mm0\n\t" /* mm0 = 0 t 0 t */
"movq %%mm0, %%mm3\n\t"
"punpckhbw %%mm5, %%mm7\n\t" /* mm7 = dest[i+1] */
"psllq $16, %%mm3\n\t" /* mm3 = t 0 t 0 */
"por %3, %%mm0\n\t" /* mm0 = 255 t 255 t */
"punpcklwd %%mm6, %%mm1\n\t" /* mm1 = rgba[i][RCOMP] dest[i][RCOMP] rgba[i][GCOMP] dest[i][GCOMP] */
"psubw %%mm3, %%mm0\n\t" /* mm0 = s[i] t[i] s[i] t[i]*/
"punpckhwd %%mm6, %%mm2\n\t" /* mm2 = rgba[i][BCOMP] dest[i][BCOMP] rgba[i][ACOMP] dest[i][ACOMP] */
"movq %%mm4, %%mm3\n\t"
"psrlq $48, %%mm3\n\t" /* mm3 = mm3 >> 48 */
"packssdw %%mm3, %%mm3\n\t" /* mm3 = 0 t 0 t */
"movq %%mm3, %%mm6\n\t"
"por %3, %%mm3\n\t" /* mm3 = 255 t 255 t */
"psllq $16, %%mm6\n\t" /* mm3 = t 0 t 0 */
"psubw %%mm6, %%mm3\n\t" /* mm3 = s[i+1] t[i+1] s[i+1] t[i+1] */
"movq %%mm4, %%mm5\n\t" /* mm5 = rgba[i+1] */
"punpcklwd %%mm7, %%mm4\n\t" /* mm4 = rgba[i+1][RCOMP] dest[i+1][RCOMP] rgba[i+1][GCOMP] dest[i+1][GCOMP] */
"punpckhwd %%mm7, %%mm5\n\t" /* mm5 = rgba[i+1][BCOMP] dest[i+1][BCOMP] rgba[i+1][ACOMP] dest[i+1][ACOMP] */
"pmaddwd %%mm0, %%mm1\n\t"
"pmaddwd %%mm3, %%mm4\n\t"
"pmaddwd %%mm0, %%mm2\n\t"
"pmaddwd %%mm3, %%mm5\n\t"
"psrld $8, %%mm1\n\t"
"psrld $8, %%mm2\n\t"
"psrld $8, %%mm4\n\t"
"packssdw %%mm2, %%mm1\n\t" /* mm2 = rgba[i] */
"psrld $8, %%mm5\n\t"
"packuswb %%mm1, %%mm1\n\t"
"packssdw %%mm5, %%mm4\n\t" /* mm5 = rgba[i+1] */
"pand %4, %%mm1\n\t"
"packuswb %%mm4, %%mm4\n\t"
"pand %2, %%mm4\n\t"
"por %%mm1, %%mm4\n\t" /* mm2 = rgba[i] rgba[i+1] */
"movq %%mm4, (%0)\n\t"
: /* no output */
: "r" (rgba[i*2]), "r" (dest[i*2]), "m" (HIGHMASK), "m" (SUBMASK), "m" (LOWMASK)
: "memory" );
}
}
__asm__("emms":::"memory");
}
if(n&1) {
GLint t = rgba[n-1][ACOMP]; /* t in [0,255] */
GLint s = 255 - t;
GLint r = (rgba[n-1][RCOMP] * t + dest[n-1][RCOMP] * s) >> 8;
GLint g = (rgba[n-1][GCOMP] * t + dest[n-1][GCOMP] * s) >> 8;
GLint b = (rgba[n-1][BCOMP] * t + dest[n-1][BCOMP] * s) >> 8;
GLint a = (rgba[n-1][ACOMP] * t + dest[n-1][ACOMP] * s) >> 8;
rgba[n-1][RCOMP] = r;
rgba[n-1][GCOMP] = g;
rgba[n-1][BCOMP] = b;
rgba[n-1][ACOMP] = a;
/*puts("odd n!");*/
}
}
#else
/* some compilers don't accept sources files without code */
void gl_mmx_dummy_function(void)
{
}
#endif